#include "connection.h"

Connection::Connection()
{
}

bool Connection::connect(QString port)
{
    if(port.startsWith("COM"))
    {
        WCHAR cPort[32];
        int charSize = 0;
        charSize = port.toWCharArray(cPort);

        cPort[charSize] = (char) 0;

        hSerial = CreateFile(cPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

        if(hSerial == INVALID_HANDLE_VALUE)
        {
            DWORD errorCode = GetLastError();

            if(errorCode == ERROR_FILE_NOT_FOUND)
            {
                alert.setText("Error: file not found");
                alert.exec();
            }
            alert.setText("Error: connection not established on port " +
                          port.fromWCharArray(cPort, 4));
            alert.exec();
            return 0;
        }

        DCB dcbSerialParams = {0};

        dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

        if(!GetCommState(hSerial, &dcbSerialParams))
        {
            //ui->statusLbl->setText("Error: Connection not created");
            alert.setText("Error: Connection not created");
            alert.exec();
            return 0;
        }

        dcbSerialParams.BaudRate = CBR_9600;
        dcbSerialParams.ByteSize = 8;
        dcbSerialParams.StopBits = ONESTOPBIT;
        dcbSerialParams.Parity = NOPARITY;

        if(!SetCommState(hSerial, &dcbSerialParams))
        {
            //ui->statusLbl->setText("Error: could not set parameters");
            alert.setText("Error: could not set parameters");
            alert.exec();
            return 0;
        }

        COMMTIMEOUTS timeouts = {0};

        timeouts.ReadIntervalTimeout = 50;
        timeouts.ReadTotalTimeoutConstant = 50;
        timeouts.ReadTotalTimeoutMultiplier = 10;
        timeouts.WriteTotalTimeoutConstant = 50;
        timeouts.WriteTotalTimeoutMultiplier = 10;

        if(!SetCommTimeouts(hSerial, &timeouts))
        {
            //ui->statusLbl->setText("Error: could not set timeouts");
            alert.setText("Error: could not set timeouts");
            alert.exec();
            return 0;
        }


    }
    else
    {
        //ui->statusLbl->setText("Error: incorrect port");
        alert.setText("Error: incorrect port");
        alert.exec();
        return 0;
    }

    return 1;
}

bool Connection::send(std::string command)
{
    int messageSize, sentSize;
    char *sendString;

    FlushFileBuffers(hSerial);

    messageSize = command.length();

    sendString = (char*) malloc(sizeof(char) * messageSize + 1);

    for(int i = 0; i < messageSize; i++)
    {
        sendString[i] = command[i];
    }
    sendString[messageSize] = (char) 0;

    if(!WriteFile(hSerial, sendString, (DWORD) messageSize, (DWORD*) &sentSize, NULL))
    {
        alert.setText("Error: message not sent");
        alert.exec();
        return 0;
    }

    return 1;
}

std::string Connection::read()
{
    int messageSize = 1, receivedSize;
    char *receiveString;
    std::string receive = "";
    receiveString = (char*) malloc(sizeof(char));
    int read = 0;

    while(read < 20)
    {
        read++;
        if(!ReadFile(hSerial, receiveString, (DWORD) messageSize, (DWORD*) &receivedSize, NULL))
        {
            alert.setText("Error: read error");
            alert.exec();
            return NULL;
        }
        else
        {
            if(receiveString[0] == '\n')
            {
                return receive;
            }
            else
            {
                receive = receive + receiveString[0];
            }
        }
    }

    return receive;
}
